package zju.lzy.dto;

import com.google.common.collect.Sets;
import lombok.Data;

import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;

/**
 * @author lzy
 */
@Data
public class MessageReq {

    private String clientId;

    /**
     * topic列表
     */
    private String[] topics;

    /**
     * 数值区间
     */
    private Integer[] valueInterval;

    /**
     * 是否告警
     */
    private Integer alert;

    /**
     * 经度区间
     */
    private Double[] lonInterval;

    /**
     * 纬度区间
     */
    private Double[] latInterval;

    /**
     * 精度区间
     */
    private Long[] timestampInterval;

    private Long reqSize;


    /**
     * 生成查询参数所产生的的sql语句
     *
     * @return
     */
    public String generateSql() {
        boolean isCond = false;
        StringBuilder sb = new StringBuilder();
        sb.append("select * from IOTData");
        if (clientId != null && clientId.length() > 0) {
            isCond = true;
            sb.append(" where");
            sb.append(String.format(" clientId='%s' ", clientId));
        }
        if (topics != null && topics.length != 0) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            sb.append(" topic in")
                    .append("(")
                    .append(String.join(",", Arrays.stream(topics).map(topic -> "'" + topic + "'").toArray(String[]::new)))
                    .append(")");
        }

        if (valueInterval != null && valueInterval.length > 0) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            if (valueInterval.length == 1) {
                sb.append(" value=").append(valueInterval[0]);
            } else {
                sb.append(" value between ")
                        .append(valueInterval[0])
                        .append(" and ")
                        .append(valueInterval[1]);
            }
        }
        if (alert != null) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            sb.append(" alert=").append(alert);
        }

        if (lonInterval != null && lonInterval.length > 0) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            if (lonInterval.length == 1) {
                sb.append(" lon=").append(lonInterval[0]);
            } else {
                sb.append(" lon between ")
                        .append(lonInterval[0])
                        .append(" and ")
                        .append(lonInterval[1]);
            }
        }

        if (latInterval != null && latInterval.length > 0) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            if (latInterval.length == 1) {
                sb.append(" lat=").append(latInterval[0]);
            } else {
                sb.append(" lat between ")
                        .append(latInterval[0])
                        .append(" and ")
                        .append(latInterval[1]);
            }
        }

        if (timestampInterval != null && timestampInterval.length > 0) {
            if (!isCond) {
                sb.append(" where");
                isCond = true;
            } else {
                sb.append(" and");
            }
            if (timestampInterval.length == 1) {
                sb.append(" timestamp=").append(timestampInterval[0]);
            } else {
                sb.append(" timestamp between ")
                        .append(timestampInterval[0])
                        .append(" and  ")
                        .append(timestampInterval[1]);
            }
        } else {
            // 如果没有限定timestamp，则默认取10000条数据
            sb.append(" order by timestamp desc limit 10000");
        }


        return sb.append(";").toString();
    }

    /**
     * 生成查询参数构建出的过滤器
     *
     * @return
     */
    public DataFilter generateFilter() {
        return data -> {
            if (clientId != null) {
                if (data.getClientId().equals(clientId)) {
                    return false;
                }
            }
            if (topics != null && topics.length != 0) {
                if (!Sets.newHashSet(topics).contains(data.getTopic())) {
                    return false;
                }
            }
            if (valueInterval != null && valueInterval.length > 0) {
                if (valueInterval.length == 1) {
                    if (!valueInterval[0].equals(data.getValue())) {
                        return false;
                    }
                } else {
                    if (data.getValue() < valueInterval[0] ||
                            data.getValue() > valueInterval[1]) {
                        return false;
                    }
                }
            }
            if (alert != null) {
                if (!alert.equals(data.getAlert())) {
                    return false;
                }
            }

            if (lonInterval != null && lonInterval.length > 0) {
                if (lonInterval.length == 1) {
                    if (lonInterval[0] != data.getLon()) {
                        return false;
                    }
                } else {
                    if (data.getLon() < lonInterval[0]
                            || data.getLon() > lonInterval[1]) {
                        return false;
                    }
                }
            }

            if (latInterval != null && latInterval.length > 0) {
                if (latInterval.length == 1) {
                    if (latInterval[0] != data.getLat()) {
                        return false;
                    }
                } else {
                    if (data.getLat() < latInterval[0]
                            || data.getLat() > latInterval[1]) {
                        return false;
                    }
                }
            }

            if (timestampInterval != null && timestampInterval.length > 0) {
                if (timestampInterval.length == 1) {
                    if (timestampInterval[0] != data.getTimestamp()) {
                        return false;
                    }
                } else {
                    if (data.getTimestamp() < timestampInterval[0]
                            || data.getTimestamp() > timestampInterval[1]) {
                        return false;
                    }
                }
            }
            return true;
        };
    }


}
